package com.ydlclass.protection;

import java.util.concurrent.atomic.AtomicInteger;


/**
 * 简单熔断器的实现
 */
public class CircuitBreaker {
    // 理论上：标准的断路器有三种状态 open close half_open, 我们为了简单，只选取两种
    private volatile boolean isOpen = false;

    //需要搜集指标 异常的数量 比例
    //总的请求数
    private AtomicInteger requestCount = new AtomicInteger(0);

    //异常的请求数
    private AtomicInteger errorRequest = new AtomicInteger(0);

    //异常的阈值
    private int maxErrorRequest;
    private float maxErrorRate;

    public CircuitBreaker(int maxErrorRequest, float maxErrorRate) {
        this.maxErrorRequest = maxErrorRequest;
        this.maxErrorRate = maxErrorRate;
    }

    //断路器的核心方法，判断是否开启
    public boolean isBreak(){
        //如果断路器打开了，直接返回true
        if(isOpen){
            return true;
        }

        //需要判断数据指标，是否满足当前的阈值
        if(errorRequest.get() > maxErrorRequest){
            this.isOpen = true;
            return true;
        }

        if(errorRequest.get() > 0 && requestCount.get() > 0 &&
        errorRequest.get() / (float)requestCount.get() > maxErrorRate){
            this.isOpen = true;
            return true;
        }
        return false;
    }

    //每次发生请求或者异常时，应该进行记录
    public void recordRequest(){
        this.requestCount.getAndIncrement();
    }
    public void recordErrorRequest(){
        this.errorRequest.getAndIncrement();
    }

    /**
     * 重置熔断器
     */
    public void reset(){
        this.isOpen = false;
        this.requestCount.set(0);
        this.errorRequest.set(0);
    }






}